﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using WorkStation.Frameworks.Configuration;
using WorkStation.Frameworks.Configuration.Elements;

namespace WorkStation.Frameworks.ServiceContainer
{
    [XmlRoot(ElementName = "workstation.frameworks.containerConfiguration")]
    public class ServiceContainerConfiguration
    {
        [XmlElement(ElementName = "containers")]
        public ServiceContainerItemConfigurationCollection ItemConfigs { get; set; }

        [XmlAttribute(AttributeName = "containerProviderType")]
        public string ContainerProviderType { get; set; }

        /// <summary>
        /// * 获取提供器对象
        /// </summary>
        /// <returns></returns>
        public IServiceContainerProvider GetProvider()
        {
            List<string> type = this.ContainerProviderType.Split(',').Select(v => v.Trim()).ToList();

            IServiceContainerProvider provider = type.Count == 1 ? Activator.CreateInstance(Type.GetType(type[0])) as IServiceContainerProvider : System.Reflection.Assembly.Load(type[1]).CreateInstance(type[0]) as IServiceContainerProvider;

            provider.Init(this);

            return provider;
        }

        /// <summary>
        /// * 初始化ServiceLocator
        /// </summary>
        public void InitServiceLocator()
        {
            var adapter = this.GetProvider().GetServiceContainer();
            
            Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => adapter);
        }
    }

    public class ServiceContainerItemConfiguration : BaseConfiguration
    {
        [XmlAttribute(AttributeName = "filePath")]
        public string FilePath { get; set; }
    }

    public class ServiceContainerItemConfigurationCollection : BaseConfigurationCollection<ServiceContainerItemConfiguration>
    {
        [XmlElement(ElementName = "container")]
        public List<ServiceContainerItemConfiguration> Configs
        {
            get { return this._list; }
            set { this._list = value; }
        }
    }
}
